package com.example.cloudcity.servlet;

import jakarta.servlet.ServletException; // 导入ServletException类，用于处理Servlet异常
import jakarta.servlet.annotation.WebServlet; // 导入WebServlet注解，用于定义Servlet
import jakarta.servlet.http.HttpServlet; // 导入HttpServlet类，作为Servlet的基类
import jakarta.servlet.http.HttpServletRequest; // 导入HttpServletRequest类，用于处理请求
import jakarta.servlet.http.HttpServletResponse; // 导入HttpServletResponse类，用于处理响应

import java.io.IOException; // 导入IOException类，用于处理输入输出异常
import java.sql.Connection; // 导入Connection接口，用于数据库连接
import java.sql.DriverManager; // 导入DriverManager类，用于获取数据库连接
import java.sql.PreparedStatement; // 导入PreparedStatement接口，用于执行预编译SQL语句
import java.sql.SQLException; // 导入SQLException类，用于处理SQL异常
import java.sql.SQLIntegrityConstraintViolationException; // 导入SQLIntegrityConstraintViolationException类，用于处理完整性约束异常
import java.sql.SQLSyntaxErrorException; // 导入SQLSyntaxErrorException类，用于处理SQL语法错误异常

@WebServlet("/UserRegisterServlet") // 定义Servlet的URL映射
public class UserRegisterServlet extends HttpServlet {
    private static final long serialVersionUID = 1L; // 序列化ID

    // 数据库连接信息
    private static final String DB_URL = "jdbc:mysql://localhost:3306/game"; // 数据库URL
    private static final String USER = "root"; // 数据库用户名
    private static final String PASS = "1234"; // 数据库密码

    // 处理POST请求
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 设置响应内容类型
        response.setContentType("text/html;charset=UTF-8"); // 设置响应的内容类型为HTML
        request.setCharacterEncoding("UTF-8"); // 设置请求的字符编码为UTF-8

        // 获取表单数据
        String username = request.getParameter("username"); // 获取用户名
        String password = request.getParameter("password"); // 获取密码
        String email = request.getParameter("email"); // 获取电子邮件
        String mobile = request.getParameter("mobile"); // 获取手机号码

        // 增强输入验证
        if (username == null || username.trim().length() < 3) { // 验证用户名长度
            request.setAttribute("msg", "用户名不能少于3个字符！"); // 设置错误消息
            request.getRequestDispatcher("register.jsp").forward(request, response); // 转发到注册页面
            return; // 结束方法
        }

        if (password == null || password.length() < 6) { // 验证密码长度
            request.setAttribute("msg", "密码不能少于6个字符！"); // 设置错误消息
            request.getRequestDispatcher("register.jsp").forward(request, response); // 转发到注册页面
            return; // 结束方法
        }

        if (email == null || !email.matches("^[A-Za-z0-9+_.-]+@(.+)$")) { // 验证电子邮件格式
            request.setAttribute("msg", "请输入有效的邮箱地址！"); // 设置错误消息
            request.getRequestDispatcher("register.jsp").forward(request, response); // 转发到注册页面
            return; // 结束方法
        }

        if (mobile == null || !mobile.matches("^1[3-9]\\d{9}$")) { // 验证手机号码格式
            request.setAttribute("msg", "请输入有效的手机号码！"); // 设置错误消息
            request.getRequestDispatcher("register.jsp").forward(request, response); // 转发到注册页面
            return; // 结束方法
        }

        try {
            String result = registerUser(username, password, email, mobile); // 调用注册用户方法
            if (result.equals("success")) { // 如果注册成功
                request.setAttribute("msg", "注册成功！"); // 设置成功消息
                response.sendRedirect("login.jsp"); // 重定向到登录页面
            } else { // 如果注册失败
                request.setAttribute("msg", result); // 设置错误消息
                request.getRequestDispatcher("register.jsp").forward(request, response); // 转发到注册页面
            }
        } catch (Exception e) { // 捕获异常
            request.setAttribute("msg", "系统错误，请稍后重试！"); // 设置错误消息
            request.getRequestDispatcher("register.jsp").forward(request, response); // 转发到注册页面
            e.printStackTrace(); // 打印异常堆栈
        }
    }

    // 注册用户的方法
    private String registerUser(String username, String password, String email, String mobile) {
        Connection conn = null; // 数据库连接
        PreparedStatement pstmt = null; // 预编译SQL语句
        PreparedStatement checkStmt = null; // 检查用户名是否存在的预编译语句
        
        try {
            Class.forName("com.mysql.cj.jdbc.Driver"); // 加载MySQL驱动
            conn = DriverManager.getConnection(DB_URL, USER, PASS); // 获取数据库连接
            
            // 首先检查用户名是否已存在
            String checkSql = "SELECT COUNT(*) FROM users WHERE username = ?"; // SQL查询语句
            checkStmt = conn.prepareStatement(checkSql); // 准备SQL语句
            checkStmt.setString(1, username); // 设置用户名参数
            java.sql.ResultSet rs = checkStmt.executeQuery(); // 执行查询
            if (rs.next() && rs.getInt(1) > 0) { // 如果用户名已存在
                return "用户名已存在！"; // 返回错误消息
            }

            // 如果用户名不存在，继续注册流程
            String sql = "INSERT INTO users (username, password, email, mobile) VALUES (?, ?, ?, ?)"; // SQL插入语句
            pstmt = conn.prepareStatement(sql); // 准备SQL语句
            pstmt.setString(1, username); // 设置用户名参数
            pstmt.setString(2, password); // 设置密码参数（TODO: 在生产环境中应该加密密码）
            pstmt.setString(3, email); // 设置电子邮件参数
            pstmt.setString(4, mobile); // 设置手机号码参数

            int rowsAffected = pstmt.executeUpdate(); // 执行插入操作
            return rowsAffected > 0 ? "success" : "注册失败，请重试！"; // 返回注册结果
            
        } catch (SQLSyntaxErrorException e) { // 捕获SQL语法错误异常
            e.printStackTrace(); // 打印异常堆栈
            return "数据库表结构错误，请确保users表已正确创建！"; // 返回错误消息
        } catch (SQLIntegrityConstraintViolationException e) { // 捕获完整性约束异常
            e.printStackTrace(); // 打印异常堆栈
            return "该用户名已被注册！"; // 返回错误消息
        } catch (SQLException e) { // 捕获SQL异常
            e.printStackTrace(); // 打印异常堆栈
            return "数据库错误：" + e.getMessage(); // 返回错误消息
        } catch (ClassNotFoundException e) { // 捕获类未找到异常
            e.printStackTrace(); // 打印异常堆栈
            return "数据库驱动加载失败！"; // 返回错误消息
        } finally { // 最终执行
            try {
                if (checkStmt != null) checkStmt.close(); // 关闭检查用户名的PreparedStatement
                if (pstmt != null) pstmt.close(); // 关闭插入用户的PreparedStatement
                if (conn != null) conn.close(); // 关闭数据库连接
            } catch (SQLException e) { // 捕获SQL异常
                e.printStackTrace(); // 打印异常堆栈
            }
        }
    }
}
